/**
 * ajax模块
 * */
import objecter from 'objecter'
import jsoner from 'jsoner'
import urler from 'urler'

export default ajax = {
	/**
	 * @desc 发送post请求
	 * @param url <String> 访问地址
	 * @param data <Object> 数据
	 * @param success <Function> 成功回调函数
	 * */
	post (url, data, success) {
		let options = this._meshOptions.apply(this, arguments)
		options.type = 'POST'
		this.request(options)
	},

	/**
	 * @desc 发送get请求
	 * @param url <String> 访问地址
	 * @param data <Object> 数据
	 * @param success <Function> 成功回调函数
	 * */
	get (url, data, success) {
		let options = this._meshOptions.apply(this, arguments)
		options.type = 'GET'
		this.request(options)
	},

	/**
	 * @desc 发送ajax请求
	 * @param options <Object> 配置
	 * {
	 *      url : <String>, 访问地址
	 *      async : <Bool>, 是否异步请求
	 *      type : <String>, 访问类型
	 *      data : <Object>, 数据
	 *      dataType : <String>, 返回值类型
	 *      success : <Function>, 功能回调函数
	 *      error : <Function>, 失败回调函数
	 *      complete : <Function> 完成回调函数
	 * }
	 * */
	request (options) {
		options = options || {}
		options.type = (options.type || 'POST').toUpperCase()
		options.dataType = options.dataType || 'json'
		options.async = options.async === false ? false : true
		let isTimeout = false
		let params = urler.formatRequestParams(options.data)

		// 创建 - 非IE6 - 第一步
		let xhr = null
		if (window.XMLHttpRequest) {
			xhr = new XMLHttpRequest()
		} else { // IE6及其以下版本浏览器
			xhr = new ActiveXObject('Microsoft.XMLHTTP')
		}

		// 接收 - 第三步
		xhr.onreadystatechange = function () {
			if (xhr.readyState == 4) {
				let status = xhr.status
				// 超时检测
				if (isTimeout) {
					return false
				}
				if (status >= 200 && status < 300) {
					objecter.isFunction(options.success) && options.success(
						jsoner.parse(xhr.responseText, options.dataType), status, xhr, options
					)
				} else {
					// error可能在的值"timeout", "error", "notmodified"，"parsererror"
					objecter.isFunction(options.error) && options.error(xhr, status, options)
				}
				objecter.isFunction(options.complete) && options.complete(xhr, xhr.responseText, options)
			}
		}

		// 连接 和 发送 - 第二步
		if (/^get$/i.test(options.type)) {
			xhr.open('GET', options.url + '?' + params, options.async)
			xhr.send(null)
		} else if (/^post$/i.test(options.type)) {
			xhr.open('POST', options.url, options.async)
			//设置表单提交时的内容类型
			xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
			xhr.send(params)
		}

		//超时处理
		if (options.timeout) {
			let timer = setTimeout(function () {
				if (xhr.readyState != 4) {
					isTimeout = true
					xhr.abort()
					clearTimeout(timer)
				}
				objecter.isFunction(options.error) && options.error(xhr, 'timeout', {message: '超时'})
				//完成回调
				objecter.isFunction(options.complete) && options.complete(xhr, 'timeout', {message: '超时'})
			}, options.timeout)
		}
	},

	//jsonp请求
	jsonp: function (options) {
		let me = this
		let cb = undefined
		options = options || {}
		cb = options.callback || options.jsonp || 'callback'

		//创建 script 标签并加入到页面中
		let callbackName = ('jsonp_' + Math.random()).replace(".", "")
		let oHead = document.getElementsByTagName('head')[0]
		options.data[cb] = callbackName
		options.url = options.url || ''
		let params = urler.formatRequestParams(options.data)
		let oS = document.createElement('script')
		let isTimeout = false
		oHead.appendChild(oS)

		//创建jsonp回调函数
		me[callbackName] = function (json) {
			if (isTimeout) {
				return false
			}
			objecter.isFunction(options.success) && options.success(json)
			//完成回调
			objecter.isFunction(options.complete) && options.complete(json)
			oHead.removeChild(oS)
			clearTimeout(oS.timer)
			me[callbackName] = null
		}

		//发送请求
		oS.src = options.url + '?' + params

		//超时处理
		if (options.timeout) {
			oS.timer = setTimeout(function () {
				isTimeout = true
				objecter.isFunction(options.error) && options.error(null, 'timeout', { message: '超时' })
				// 完成回调
				objecter.isFunction(options.complete) && options.complete(null, 'timeout', { message: '超时' })
				me[callbackName] = null
				oHead.removeChild(oS)
			}, options.timeout)
		}
	},

	// 传输base64图片
	sendBase64: function(){
		var me = this
		var input = document.querySelector("input[type=file]")
		var reader = new FileReader()
		reader.readAsDataURL(input.files[0])
		reader.onload = function (evt){
			let base64 = reader.result
			// 重点来了 ajax在传输过程中 加号会变成空格 base64里是有加号的我不幸掉进了这个坑……
			// 把+替换成编码 %2B是加号的编码
			let newBase64 = base64.replace(/\+/g, "%2B")
			me.request({
				data : {newBase64 : newBase64}
			})
		}

		/*
		 保存
		 $base64 = $_POST['newBase64']
		 // png格式
		 //  把头掐了
		 $image = base64_decode(str_replace('data:image/pngbase64,' '', $base64))
		 file_put_contents('text.png'', $image)
		 //jpeg
		 $image = base64_decode(str_replace('data:image/jpegbase64,' '', $base64))
		 file_put_contents('text.jpg'', $image)
		 */
	},

	/**
	 * @desc 匹配配置
	 * @param url <String> 访问地址
	 * @param data <Object> 数据
	 * @param success <Function> 成功回调函数
	 * */
	_meshOptions (url, data, success) {
		let options = {}
		// 判断是否是对象配置
		if (objecter.isPlainObject(url)) {
			options = url || options
		} else {
			options.url = url || ''
			if (objecter.isPlainObject(data)) {
				options.data = data
			}
		}
		options.success = objecter.isFunction(success) ? success : function(){}

		return options
	}
}